package service

import (
	"errors"
	"io"
	"mime/multipart"
	"os"
	"path"
	"strings"
	"time"
	"zsc-boot/app/system_layer/model"
	"zsc-boot/app/system_layer/model/request"
	"zsc-boot/core"
	"zsc-boot/core/orm"
	"zsc-boot/core/utils"
)

const (
	slicePath = "./file_slice/"
)

var ServiceDocumentService = new(serviceDocumentService)

type serviceDocumentService struct {
}

// CreateDocument 创建文件
func (s *serviceDocumentService) createDocument(Document model.ServiceDocument) (err error, fileInfo model.ServiceDocument) {
	err = orm.GetDb().Create(&Document).Error
	return err, Document
}

// GetServiceDocument 获取文件详情
func (s *serviceDocumentService) GetServiceDocument(id uint) (err error, resp model.ServiceDocument) {
	err = orm.GetDb().Where("id = ?", id).First(&resp).Error
	return
}

// GetServiceDocumentList 获取文件列表
func (s *serviceDocumentService) GetServiceDocumentList(info request.ServiceDocoreumentSearch) (err error, list interface{}, total int64) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	var serviceDocuments []model.ServiceDocument
	db := orm.GetDb().Model(&model.ServiceDocument{})
	if info.FileName != "" {
		db.Where("file_name like ?", "%"+info.FileName+"%")
	}

	err = db.Count(&total).Error
	if err != nil {
		return
	}
	err = db.Limit(limit).Offset(offset).Order("updated_at desc").Find(&serviceDocuments).Error
	return err, serviceDocuments, total
}

// SingleFileUpload 上传单文件
func (s *serviceDocumentService) SingleFileUpload(doc model.ServiceDocument, file *multipart.FileHeader) (err error, fileInfo model.ServiceDocument) {
	doc.FileName = file.Filename
	err, suffix, trimSuffix, tag := s.filenameHandling(file.Filename)
	if err != nil {
		return
	}
	doc.Tag = tag
	doc.FileMd5 = utils.MD5V([]byte(trimSuffix)) + "_" + time.Now().Format("20060102150405") + suffix
	f, err := file.Open()
	if err != nil {
		core.GetLogger().Error(err.Error())
		return errors.New("文件打开失败,请检查上传的文件是否正确"), fileInfo
	}
	defer f.Close()
	doc.Path = "data_dir/" + doc.Tag + "/" + doc.FileMd5
	out, err := os.Create(doc.Path)
	if err != nil {
		core.GetLogger().Error("创建文件存储路径出错,请检查是否拥有相应权限" + err.Error())
		return errors.New("创建储存文件路径出错,请检查是否拥有相应权限"), fileInfo
	}
	defer out.Close()
	_, err = io.Copy(out, f)
	if err != nil {
		core.GetLogger().Error("文件储存失败" + err.Error())
		return errors.New("文件储存失败"), fileInfo
	}
	doc.FileSize = file.Size
	err, fileInfo = s.createDocument(doc)
	if err != nil {
		core.GetLogger().Error("文件记录创建失败" + err.Error())
		return errors.New("文件记录创建失败"), fileInfo
	}
	return
}

func (s *serviceDocumentService) filenameHandling(fileName string) (err error, suffix string, trimSuffix string, tag string) {
	suffix = path.Ext(fileName) // 取后缀
	tag = strings.Split(suffix, ".")[1]
	err = os.MkdirAll("data_dir/"+tag, os.ModePerm)
	if err != nil {
		core.GetLogger().Error("创建文件存储路径出错,请检查是否拥有相应权限" + err.Error())
		err = errors.New("创建文件存储路径出错,请检查是否拥有相应权限")
		return
	}
	trimSuffix = strings.TrimSuffix(fileName, suffix) // 截取文件名
	return
}

func (s *serviceDocumentService) CheckMd5(content []byte, chunkMd5 string) (CanUpload bool) {
	fileMd5 := utils.MD5V(content)
	if fileMd5 == chunkMd5 {
		return true // 可以继续上传
	} else {
		return false // 切片不完整，废弃
	}
}
